import type { Recordable } from '@vben/types';

import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { InfraCodegenApi } from '#/api/infra/codegen';
import type { SystemMenuApi } from '#/api/system/menu';

import { h } from 'vue';

import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import { IconifyIcon } from '@vben/icons';
import { handleTree } from '@vben/utils';

import { getDataSourceConfigList } from '#/api/infra/data-source-config';
import { getMenuList } from '#/api/system/menu';
import { $t } from '#/locales';
import { getRangePickerDefaultProps } from '#/utils';

/** 导入数据库表的表单 */
export function useImportTableFormSchema(): VbenFormSchema[] {
  return [
    {
      fieldName: 'dataSourceConfigId',
      label: $t('views.infra.codegen.dataSourceConfig'),
      component: 'ApiSelect',
      componentProps: {
        api: async () => {
          const data = await getDataSourceConfigList();
          return data.map((item) => ({
            label: item.name,
            value: item.id,
          }));
        },
        autoSelect: 'first',
        placeholder: $t('views.infra.codegen.dataSourceConfigPlaceholder'),
      },
      rules: 'selectRequired',
    },
    {
      fieldName: 'name',
      label: $t('views.infra.codegen.tableName'),
      component: 'Input',
      componentProps: {
        allowClear: true,
        placeholder: $t('views.infra.codegen.tableNamePlaceholder'),
      },
    },
    {
      fieldName: 'comment',
      label: $t('views.infra.codegen.tableComment'),
      component: 'Input',
      componentProps: {
        allowClear: true,
        placeholder: $t('views.infra.codegen.tableCommentPlaceholder'),
      },
    },
  ];
}

/** 导入数据库表表格列定义 */
export function useImportTableColumns(): VxeTableGridOptions['columns'] {
  return [
    { type: 'checkbox', width: 40 },
    { field: 'name', title: $t('views.infra.codegen.tableName'), minWidth: 200 },
    { field: 'comment', title: $t('views.infra.codegen.tableComment'), minWidth: 200 },
  ];
}

/** 基本信息表单的 schema */
export function useBasicInfoFormSchema(): VbenFormSchema[] {
  return [
    {
      fieldName: 'tableName',
      label: $t('views.infra.codegen.tableName'),
      component: 'Input',
      componentProps: {
        placeholder: $t('views.infra.codegen.tableNamePlaceholder'),
      },
      rules: 'required',
    },
    {
      fieldName: 'tableComment',
      label: $t('views.infra.codegen.tableComment'),
      component: 'Input',
      componentProps: {
        placeholder: $t('views.infra.codegen.tableCommentPlaceholder'),
      },
      rules: 'required',
    },
    {
      fieldName: 'className',
      label: $t('views.infra.codegen.className'),
      component: 'Input',
      componentProps: {
        placeholder: $t('views.infra.codegen.classNamePlaceholder'),
      },
      rules: 'required',
      help: $t('views.infra.codegen.classNameHelpMessage'),
    },
    {
      fieldName: 'author',
      label: $t('views.infra.codegen.author'),
      component: 'Input',
      componentProps: {
        placeholder: $t('views.infra.codegen.authorPlaceholder'),
      },
      rules: 'required',
    },
    {
      fieldName: 'remark',
      label: $t('common.remark'),
      component: 'Textarea',
      componentProps: {
        rows: 3,
        placeholder: $t('common.remarkPlaceholder'),
      },
      formItemClass: 'md:col-span-2',
    },
  ];
}

/** 生成信息表单基础 schema */
export function useGenerationInfoBaseFormSchema(): VbenFormSchema[] {
  return [
    {
      component: 'Select',
      fieldName: 'templateType',
      label: $t('views.infra.codegen.templateType'),
      componentProps: {
        options: getDictOptions(
          DICT_TYPE.INFRA_CODEGEN_TEMPLATE_TYPE,
          'number',
        ),
        class: 'w-full',
      },
      rules: 'selectRequired',
    },
    {
      component: 'Select',
      fieldName: 'frontType',
      label: $t('views.infra.codegen.frontType'),
      componentProps: {
        options: getDictOptions(DICT_TYPE.INFRA_CODEGEN_FRONT_TYPE, 'number'),
        class: 'w-full',
      },
      rules: 'selectRequired',
    },
    {
      component: 'Select',
      fieldName: 'scene',
      label: $t('views.infra.codegen.scene'),
      componentProps: {
        options: getDictOptions(DICT_TYPE.INFRA_CODEGEN_SCENE, 'number'),
        class: 'w-full',
      },
      rules: 'selectRequired',
    },
    {
      fieldName: 'parentMenuId',
      label: $t('views.infra.codegen.parentMenu'),
      help: $t('views.infra.codegen.parentMenuHelpMessage'),
      component: 'ApiTreeSelect',
      componentProps: {
        allowClear: true,
        api: async () => {
          const data = await getMenuList();
          data.unshift({
            id: 0,
            name: '顶级菜单',
          } as SystemMenuApi.Menu);
          return handleTree(data);
        },
        class: 'w-full',
        labelField: 'name',
        valueField: 'id',
        childrenField: 'children',
        placeholder: $t('views.infra.codegen.parentMenuPlaceholder'),
        filterTreeNode(input: string, node: Recordable<any>) {
          if (!input || input.length === 0) {
            return true;
          }
          const name: string = node.label ?? '';
          if (!name) return false;
          return name.includes(input) || $t(name).includes(input);
        },
        showSearch: true,
        treeDefaultExpandedKeys: [0],
      },
      rules: 'selectRequired',
      renderComponentContent() {
        return {
          title({ label, icon }: { icon: string; label: string }) {
            const components = [];
            if (!label) return '';
            if (icon) {
              components.push(h(IconifyIcon, { class: 'size-4', icon }));
            }
            components.push(h('span', { class: '' }, $t(label || '')));
            return h('div', { class: 'flex items-center gap-1' }, components);
          },
        };
      },
    },
    {
      component: 'Input',
      fieldName: 'moduleName',
      label: $t('views.infra.codegen.moduleName'),
      help: $t('views.infra.codegen.moduleNameHelpMessage'),
      rules: 'required',
    },
    {
      component: 'Input',
      fieldName: 'businessName',
      label: $t('views.infra.codegen.businessName'),
      help: $t('views.infra.codegen.businessNameHelpMessage'),
      rules: 'required',
    },
    {
      component: 'Input',
      fieldName: 'className',
      label: $t('views.infra.codegen.className2'),
      help: $t('views.infra.codegen.className2HelpMessage'),
      rules: 'required',
    },
    {
      component: 'Input',
      fieldName: 'classComment',
      label: $t('views.infra.codegen.classComment'),
      help: $t('views.infra.codegen.classCommentHelpMessage'),
      rules: 'required',
    },
  ];
}

/** 树表信息 schema */
export function useGenerationInfoTreeFormSchema(
  columns: InfraCodegenApi.CodegenColumn[] = [],
): VbenFormSchema[] {
  return [
    {
      component: 'Divider',
      fieldName: 'treeDivider',
      label: '',
      renderComponentContent: () => {
        return {
          default: () => [$t('views.infra.codegen.treeDivider')],
        };
      },
      formItemClass: 'md:col-span-2',
    },
    {
      component: 'Select',
      fieldName: 'treeParentColumnId',
      label: $t('views.infra.codegen.treeParentColumn'),
      help: $t('views.infra.codegen.treeParentColumnHelpMessage'),
      componentProps: {
        class: 'w-full',
        allowClear: true,
        placeholder: $t('views.infra.codegen.treeParentColumnPlaceholder'),
        options: columns.map((column) => ({
          label: column.columnName,
          value: column.id,
        })),
      },
      rules: 'selectRequired',
    },
    {
      component: 'Select',
      fieldName: 'treeNameColumnId',
      label: $t('views.infra.codegen.treeNameColumn'),
      help: $t('views.infra.codegen.treeNameColumnHelpMessage'),
      componentProps: {
        class: 'w-full',
        allowClear: true,
        placeholder: $t('views.infra.codegen.treeNameColumnPlaceholder'),
        options: columns.map((column) => ({
          label: column.columnName,
          value: column.id,
        })),
      },
      rules: 'selectRequired',
    },
  ];
}

/** 主子表信息 schema */
export function useGenerationInfoSubTableFormSchema(
  columns: InfraCodegenApi.CodegenColumn[] = [],
  tables: InfraCodegenApi.CodegenTable[] = [],
): VbenFormSchema[] {
  return [
    {
      component: 'Divider',
      fieldName: 'subDivider',
      label: '',
      renderComponentContent: () => {
        return {
          default: () => [$t('views.infra.codegen.subDivider')],
        };
      },
      formItemClass: 'md:col-span-2',
    },
    {
      component: 'Select',
      fieldName: 'masterTableId',
      label: $t('views.infra.codegen.masterTable'),
      help: $t('views.infra.codegen.masterTableHelpMessage'),
      componentProps: {
        class: 'w-full',
        allowClear: true,
        placeholder: $t('views.infra.codegen.masterTablePlaceholder'),
        options: tables.map((table) => ({
          label: `${table.tableName}：${table.tableComment}`,
          value: table.id,
        })),
      },
      rules: 'selectRequired',
    },
    {
      component: 'Select',
      fieldName: 'subJoinColumnId',
      label: $t('views.infra.codegen.subJoinColumn'),
      help: $t('views.infra.codegen.subJoinColumnHelpMessage'),
      componentProps: {
        class: 'w-full',
        allowClear: true,
        placeholder: $t('views.infra.codegen.subJoinColumnPlaceholder'),
        options: columns.map((column) => ({
          label: `${column.columnName}:${column.columnComment}`,
          value: column.id,
        })),
      },
      rules: 'selectRequired',
    },
    {
      component: 'RadioGroup',
      fieldName: 'subJoinMany',
      label: $t('views.infra.codegen.subJoinMany'),
      help: $t('views.infra.codegen.subJoinManyHelpMessage'),
      componentProps: {
        class: 'w-full',
        allowClear: true,
        placeholder: $t('views.infra.codegen.subJoinManyPlaceholder'),
        options: [
          {
            label: $t('views.infra.codegen.subJoinManyOptions.oneToMany'),
            value: true,
          },
          {
            label: $t('views.infra.codegen.subJoinManyOptions.oneToOne'),
            value: false,
          },
        ],
      },
      rules: 'required',
    },
  ];
}

/** 列表的搜索表单 */
export function useGridFormSchema(): VbenFormSchema[] {
  return [
    {
      fieldName: 'tableName',
      label: $t('views.infra.codegen.tableName'),
      component: 'Input',
      componentProps: {
        allowClear: true,
        placeholder: $t('views.infra.codegen.tableNamePlaceholder'),
      },
    },
    {
      fieldName: 'tableComment',
      label: $t('views.infra.codegen.tableComment'),
      component: 'Input',
      componentProps: {
        allowClear: true,
        placeholder: $t('views.infra.codegen.tableCommentPlaceholder'),
      },
    },
    {
      fieldName: 'createTime',
      label: $t('common.createTime'),
      component: 'RangePicker',
      componentProps: {
        ...getRangePickerDefaultProps(),
        allowClear: true,
      },
    },
  ];
}

/** 列表的字段 */
export function useGridColumns(
  getDataSourceConfigName?: (dataSourceConfigId: number) => string | undefined,
): VxeTableGridOptions['columns'] {
  return [
    { type: 'checkbox', width: 40 },
    {
      field: 'dataSourceConfigId',
      title: $t('views.infra.codegen.dataSourceConfig'),
      minWidth: 120,
      formatter: ({ cellValue }) => getDataSourceConfigName?.(cellValue) || '-',
    },
    {
      field: 'tableName',
      title: $t('views.infra.codegen.tableName'),
      minWidth: 200,
    },
    {
      field: 'tableComment',
      title: $t('views.infra.codegen.tableComment'),
      minWidth: 200,
    },
    {
      field: 'className',
      title: $t('views.infra.codegen.className'),
      minWidth: 200,
    },
    {
      field: 'createTime',
      title: $t('common.createTime'),
      minWidth: 180,
      formatter: 'formatDateTime',
    },
    {
      field: 'updateTime',
      title: $t('common.updateTime'),
      minWidth: 180,
      formatter: 'formatDateTime',
    },
    {
      title: $t('common.action'),
      width: 280,
      fixed: 'right',
      slots: { default: 'actions' },
    },
  ];
}

/** 代码生成表格列定义 */
export function useCodegenColumnTableColumns(): VxeTableGridOptions['columns'] {
  return [
    { field: 'columnName', title: $t('views.infra.codegen.columnName'), minWidth: 130 },
    {
      field: 'columnComment',
      title: $t('views.infra.codegen.columnComment'),
      minWidth: 100,
      slots: { default: 'columnComment' },
    },
    { field: 'dataType', title: $t('views.infra.codegen.dataType'), minWidth: 100 },
    {
      field: 'javaType',
      title: $t('views.infra.codegen.javaType'),
      minWidth: 130,
      slots: { default: 'javaType' },
      params: {
        options: [
          { label: 'Long', value: 'Long' },
          { label: 'String', value: 'String' },
          { label: 'Integer', value: 'Integer' },
          { label: 'Double', value: 'Double' },
          { label: 'BigDecimal', value: 'BigDecimal' },
          { label: 'LocalDateTime', value: 'LocalDateTime' },
          { label: 'Boolean', value: 'Boolean' },
        ],
      },
    },
    {
      field: 'javaField',
      title: $t('views.infra.codegen.javaField'),
      minWidth: 100,
      slots: { default: 'javaField' },
    },
    {
      field: 'createOperation',
      title: $t('views.infra.codegen.createOperation'),
      width: 40,
      slots: { default: 'createOperation' },
    },
    {
      field: 'updateOperation',
      title: $t('views.infra.codegen.updateOperation'),
      width: 40,
      slots: { default: 'updateOperation' },
    },
    {
      field: 'listOperationResult',
      title: $t('views.infra.codegen.listOperationResult'),
      width: 40,
      slots: { default: 'listOperationResult' },
    },
    {
      field: 'listOperation',
      title: $t('views.infra.codegen.listOperation'),
      width: 40,
      slots: { default: 'listOperation' },
    },
    {
      field: 'listOperationCondition',
      title: $t('views.infra.codegen.listOperationCondition'),
      minWidth: 100,
      slots: { default: 'listOperationCondition' },
      params: {
        options: [
          { label: '=', value: '=' },
          { label: '!=', value: '!=' },
          { label: '>', value: '>' },
          { label: '>=', value: '>=' },
          { label: '<', value: '<' },
          { label: '<=', value: '<=' },
          { label: 'LIKE', value: 'LIKE' },
          { label: 'BETWEEN', value: 'BETWEEN' },
        ],
      },
    },
    {
      field: 'nullable',
      title: $t('views.infra.codegen.nullable'),
      width: 60,
      slots: { default: 'nullable' },
    },
    {
      field: 'htmlType',
      title: $t('views.infra.codegen.htmlType'),
      width: 130,
      slots: { default: 'htmlType' },
      params: {
        options: [
          { label: $t('views.infra.codegen.htmlTypeOptions.input'), value: 'input' },
          { label: $t('views.infra.codegen.htmlTypeOptions.textarea'), value: 'textarea' },
          { label: $t('views.infra.codegen.htmlTypeOptions.select'), value: 'select' },
          { label: $t('views.infra.codegen.htmlTypeOptions.radio'), value: 'radio' },
          { label: $t('views.infra.codegen.htmlTypeOptions.checkbox'), value: 'checkbox' },
          { label: $t('views.infra.codegen.htmlTypeOptions.datetime'), value: 'datetime' },
          { label: $t('views.infra.codegen.htmlTypeOptions.imageUpload'), value: 'imageUpload' },
          { label: $t('views.infra.codegen.htmlTypeOptions.fileUpload'), value: 'fileUpload' },
          { label: $t('views.infra.codegen.htmlTypeOptions.editor'), value: 'editor' },
        ],
      },
    },
    {
      field: 'dictType',
      title: $t('views.infra.codegen.dictType'),
      width: 120,
      slots: { default: 'dictType' },
    },
    {
      field: 'example',
      title: $t('views.infra.codegen.example'),
      minWidth: 100,
      slots: { default: 'example' },
    },
  ];
}
